package util;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.AccelerateInterpolator;
import android.widget.RelativeLayout;

import com.gonfre.quientelo.FiltersFragment;
import com.gonfre.quientelo.R;

import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * Clase con funciones estáticas comunes
 *
 * @author xionjames
 * @version 0.1
  */
public class Tools {

    public static Bitmap circleBitmap(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        canvas.drawCircle(
                bitmap.getWidth() / 2,
                bitmap.getHeight() / 2,
                (bitmap.getHeight() < bitmap.getWidth() ? bitmap.getHeight() : bitmap.getWidth()) / 2,
                paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

    public static Bitmap circleBitmap(Drawable drawable) {
        Bitmap bitmap = getBitmapFromDrawable(drawable);
        return circleBitmap(bitmap);
    }

    public static Bitmap getBitmapFromDrawable(Drawable drawable){
        Bitmap bitmap = null;
        try {
            BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable;
            bitmap = bitmapDrawable.getBitmap();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    public static Date serverDate2JavaDate(String datetime) {
        DateFormat inFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US);
        Date inDate = null;
        try {
            inDate = inFormat.parse(datetime);
        } catch (ParseException e) {
            inDate = null;
        }

        return inDate;
    }

    public static String formatDate(String datetime, Context context) {
        Date inDate = serverDate2JavaDate(datetime);
        if (inDate == null) {
            return null;
        }
        DateFormat dateFormat = android.text.format.DateFormat.getDateFormat(context);
        DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(context);
        return dateFormat.format(inDate) + ", " + timeFormat.format(inDate);
    }

    public static String getShortTimeFromDate(String datetime, Context context) {
        final long _LIMIT = 0;
        Date inDate = serverDate2JavaDate(datetime);
        Date currentDate = Calendar.getInstance().getTime();

        long secs = (currentDate.getTime() - inDate.getTime()) / 1000;

        if (secs >= _LIMIT) {
            DateFormat timeFormat = android.text.format.DateFormat.getTimeFormat(context);
            return timeFormat.format(inDate);
        } else {
            long mins = new Double(Math.ceil(secs / 60)).longValue() + 1;
            return "< " + mins + " min";
        }
    }

    public static int dpToPx(int dp, DisplayMetrics displayMetrics) {
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    public static int pxToDp(int px, DisplayMetrics displayMetrics) {
        int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return dp;
    }

    public static void toggleSecondBar(View secondBar) {
        if (isVisibleSecondBar(secondBar)) {
            secondBar.animate()
                    .translationY(0)
                    .setInterpolator(new AccelerateInterpolator())
                    .start();
        } else {
            ViewGroup.LayoutParams vlp = secondBar.getLayoutParams();
            int margin = ((RelativeLayout.LayoutParams) vlp).topMargin;

            secondBar.animate()
                    .translationY(secondBar.getBottom() - margin)
                    .setInterpolator(new AccelerateInterpolator())
                    .start();
        }
    }

    public static boolean isVisibleSecondBar(View secondBar) {
        return (secondBar.getTranslationY() > 0);
    }

    public static void initSecondBar(final View secondBar, final RelativeLayout mainLayout, final Toolbar toolbar) {
        //init Second bar
        secondBar.setVisibility(View.VISIBLE);

        mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
        {
            @Override
            public void onGlobalLayout()
            {
                // gets called after layout has been done but before display.
                mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                if (toolbar == null) {
                    hideSecondBar(secondBar, 0);
                } else {
                    hideSecondBar(secondBar, Tools.pxToDp(toolbar.getHeight(), secondBar.getResources().getDisplayMetrics()));
                }
            }
        });
    }

    public static void hideSecondBar(View secondBar, int toolbarHeight) {

        RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams)secondBar.getLayoutParams();

        int dpHeigh = Tools.pxToDp(secondBar.getHeight(), secondBar.getResources().getDisplayMetrics());
        int pxTopMargin = Tools.dpToPx( dpHeigh*(-1) + toolbarHeight - 2, secondBar.getResources().getDisplayMetrics());

        RelativeLayout.LayoutParams newParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        newParams.setMargins(rlp.leftMargin, Math.round(pxTopMargin), rlp.rightMargin, rlp.bottomMargin);
        secondBar.setLayoutParams(newParams);
    }

    public static String getShowRangeBarValue(long value) {
        return getFormatValue(value * 1000);
    }

    public static long getNoShowRangeBarValue(long value) {
        return value * 1000;
    }
    public static int getRangeBarValue(long value) {
        return (int)(value / 1000);
    }

    public static String getFormatValue(long value) {
        return NumberFormat.getNumberInstance(Locale.getDefault()).format(value);
    }

    /*public static long getValueFromFormatted(String value) {
        return Long.parseLong(value.replaceAll("\\.", "").replaceAll("\\,", ""), 10);
    }*/

    public static int calculateRangeMinVal(long val) {
        String value = String.valueOf(getRangeBarValue(val));
        String first2Digit = value.substring(0, (value.length()>1 ? 2 : 1));
        int digits = Integer.parseInt(first2Digit, 10);
        if (digits > 10) {
            digits -= 10; // <<<<<aqui el point
        } else {
            digits -= 2;
        }

        if (digits < 0) {
            return 0;
        }

        return (int) (digits * Math.pow(10, value.length()-2));
    }

    public static int calculateRangeMaxVal(long val) {
        String value = String.valueOf(getRangeBarValue(val));
        String firstDigit = String.valueOf( value.charAt(0) );
        int digit = Integer.parseInt(firstDigit, 10);
        digit += 1; //<<< aca el point

        return (int) (digit * Math.pow(10, value.length()-1));
    }

    public static FilterValues createFilterValuesFromResponse(Response res, int type) {
        FilterValues filters = new FilterValues();

        if (type == FiltersFragment.SELLER) {

            int size = res.getListLength("request_list");
            for (int i=0; i<size; i++) {
                String cat = res.getBodyValueArrayStr("request_list", i, "category");
                String loc = res.getBodyValueArrayStr("request_list", i, "location");
                filters.addCategory(cat);
                filters.addLocation(loc);
            }
        } else if (type == FiltersFragment.PURCHASER) {

            long priceMin = 999999999;
            long priceMax = 0;
            int size = res.getListLength("price_list");
            for (int i=0; i<size; i++) {
                String loc = res.getBodyValueArrayStr("request_list", i, "location_seller");
                filters.addLocation(loc);

                long pri = res.getBodyValueArrayDouble("request_list", i, "price").longValue();
                if (pri > priceMax) {
                    priceMax = pri;
                }
                if (pri < priceMin) {
                    priceMin = pri;
                }
            }

            filters.setPricesLimits(priceMin, priceMax);

        } else {}

        return filters;
    }
}
